<?php
/**
 *
 * 回调基础类
 * @author widyhu
 *
 */
class WxPayNotify extends WxPayNotifyReply
{
    /**
     *
     * 回调入口
     * @param bool $needSign  是否需要签名输出
     */
    final public function Handle($needSign = true)
    {
        $msg = "OK";
        //当返回false的时候，表示notify中调用NotifyCallBack回调失败获取签名校验失败，此时直接回复失败
        $result = WxpayApi::notify(array($this, 'NotifyCallBack'), $msg);
        if ($result == false) {
            $this->SetReturn_code("FAIL");
            $this->SetReturn_msg($msg);
            $this->ReplyNotify(false);
            return;
        } else {
            //该分支在成功回调到NotifyCallBack方法，处理完成之后流程
            $this->SetReturn_code("SUCCESS");
            $this->SetReturn_msg("OK");
        }
        $this->ReplyNotify($needSign);
    }

    /**
     *
     * notify回调方法，该方法中需要赋值需要输出的参数,不可重写
     * @param array $data
     * @return true回调出来完成不需要继续回调，false回调处理未完成需要继续回调
     */
    final public function NotifyCallBack($data)
    {
        $msg    = "OK";
        $result = $this->NotifyProcess($data, $msg);

        if ($result == true) {
            $this->SetReturn_code("SUCCESS");
            $this->SetReturn_msg("OK");
        } else {
            $this->SetReturn_code("FAIL");
            $this->SetReturn_msg($msg);
        }
        return $result;
    }

    /**
     *
     * 回复通知
     * @param bool $needSign 是否需要签名输出
     */
    final private function ReplyNotify($needSign = true)
    {
        //如果需要签名
        if ($needSign == true && $this->GetReturn_code($return_code) == "SUCCESS") {
            $this->SetSign();
        }
        WxpayApi::replyNotify($this->ToXml());
    }

    //查询订单
    public function Queryorder($transaction_id)
    {
        $input = new WxPayOrderQuery();
        $input->SetTransaction_id($transaction_id);
        $result = WxPayApi::orderQuery($input);
        if (array_key_exists("return_code", $result)
            && array_key_exists("result_code", $result)
            && $result["return_code"] == "SUCCESS"
            && $result["result_code"] == "SUCCESS") {
            return true;
        }
        return false;
    }
    /**
     * 回调方法入口，子类可重写该方法
     * 注意：
     * 1、微信回调超时时间为2s，建议用户使用异步处理流程，确认成功之后立刻回复微信服务器
     * 2、微信服务器在调用失败或者接到回包为非确认包的时候，会发起重试，需确保你的回调是可以重入
     * @param array $data 回调解释出的参数
     * @param string $msg 如果回调处理失败，可以将错误信息输出到该方法
     * @return true回调出来完成不需要继续回调，false回调处理未完成需要继续回调
     */
    public function NotifyProcess($data, &$msg)
    {
        // if(!array_key_exists("transaction_id", $data)){
        //     $msg = "输入参数不正确";
        //     return false;
        // }
        //查询订单，判断订单真实性
        if (!$this->Queryorder($data["transaction_id"])) {
            $msg = "订单查询失败";
            return false;
        }
        log::write('NotifyProcess' . print_r($data, 1));
        $arr = explode('|', $data['attach']);
        if ($arr[0] == 'CPIC-ZF') {
            //太平洋保险支付
            $this->wxzhifu($data, $arr[1]);
        } elseif ($arr[0] == 'CPIC-CZ') {
            //太平洋保险充值
            $this->wxchongzhi($data, $arr[1], $arr[2], $arr[3]);
        }
        return true;
    }
    public function wxzhifu($data, $store)
    {
        if ($store < 1) {
            return false;
        }
        $dt['data']['remake']            = '微信支付';
        $dt['data']['orderid']           = $data['out_trade_no'];
        $dt['data']['thirdOrder']        = '';
        $dt['data']['amount']            = $data['total_fee'] / 100;
        $dt['data']['acc_amount']        = $data['total_fee'] / 100;
        $dt['data']['payer_acc_type']    = '3';
        $dt['data']['payer_account']     = '';
        $dt['data']['receiver_acc_type'] = '3';
        $dt['data']['receiver_account']  = $data['mch_id'];
        $dt['data']['gateway_trans_id']  = $data['transaction_id'];
        $dt['data']['rtrans_id']         = '';
        $dt['data']['note']              = '';
        $dt['data']['appId']             = $store;
        $res                             = AB('Base.ordersPayOrderLog_2', $dt);
        if ($res['error'] != '00') {
            return false;
        }
        //线下商户线上支付成功后通知第三方平台支付成功
        $orderType = substr($data['out_trade_no'], 14, 3); //订单类型
        if ($orderType == '204') {
            $arr['data'] = array(
                'orderid'  => $data['out_trade_no'],
                'platform' => $store, //平台ID(分销商ID)
            );
            //无论成功还是失败，只通知一次
            AB("QRPays.getNotice", $arr);
        }

    }
    public function wxchongzhi($data, $store, $memberId, $mobile)
    {
        if ($store < 1) {
            return false;
        }
        //充值前先查询流水表，如果有值，就不必继续操作了，不管成功失败（微信充值流水固定，一笔交易一个订单号，不可重复，失败了也不行，虽然可能性不大）
        $dt4['data']['orderidx'] = $data['out_trade_no']; //微信返回的订单号
        $method                  = 'Base.selectGetOrderPayFlow';
        $res4                    = AB($method, $dt4);
        //查到流水了
        if (is_array($res4['data'])) {
            return true;
        }
        $account = D("Pay")->getUserDetail($mobile); //充值主账户
        //第一步写充值流水充值
        if (!$account) {
            return false;
        }
        $data3['data'] = array(
            'member_id'     => $memberId,
            'member_mobile' => $mobile,
            'store_id'      => $store,
            'type'          => '02',
            'amount'        => $data['total_fee'] / 100,
            'ref_orderid'   => '',
            'pacc_type'     => '3', //付款类型，微信
            'paccount'      => '', //付款帐号
            'racc_type'     => '3', //收款类型，微信
            'raccount'      => $account, //收款帐号
            'ptrans_id'     => '',
            'rtrans_id'     => '',
            'orderid'       => $data['out_trade_no'],
            'order_type'    => '3',
            'status'        => '2',
            'note'          => '微信充值-太平洋保险-充值中',
        );
        $method  = 'Base.ordersRechargelog';
        $result3 = AB($method, $data3);
        if ($result3['error'] != '00') {
            return false;
        }
        //第二步写充值
        $data1 = array(
            'mainIdx'    => $account,
            'amount'     => $data['total_fee'] / 100,
            'amountType' => '00',
            'orderIdx'   => $data['out_trade_no'],
            'notifyUrl'  => '',
        );
        $method  = 'Account.recharge';
        $result1 = AC($method, $data1);
        //充值失败
        if ($result1['error'] != '10') {
            return false;
        }
        //第三步 改写流水
        $data2['data'] = array(
            'amount'    => $data['total_fee'] / 100,
            'paccount'  => $data['mch_id'],
            'raccount'  => $account,
            'ptrans_id' => $data['transaction_id'], //微信支付流水
            'rtrans_id' => $result1['result']['recharge_idx'], //可伴账户流水
            'status'    => '10',
            'note'      => '微信充值-太平洋保险-充值成功',
            'tsd'       => $result3['data'],
        );
        $method  = 'Base.ordersRechargelog_2';
        $result2 = AB($method, $data2);
        if ($result2['error'] == '00') {
            return true;
        } else {
            return false;
        }

    }
}
